Angular 使用笔记【依赖注入(有例子)】【constructor & ongOnInit】 【组件传值】【ngSwitch】 | 您所在的位置:网站首页 › string constructor依赖 › Angular 使用笔记【依赖注入(有例子)】【constructor & ongOnInit】 【组件传值】【ngSwitch】 |
angular中的服务:多个组件可以共享同一数据,服务可从远程服务器中异步获取数据。在组件中使用服务的步骤:1. 导入服务; 2. 声明服务; 3. 注入服务@Injectable({provideIn: 'root'})是每个angular服务定义中的基本元素。你可以在三种位置之一设置元数据,以便在应用的不同层级使用提供商来配置注入器:1. 服务本身的@Injectable()装饰器【provideIn】; 2. NgModule的@NgModule()装饰器 【provides】; 3. 组件的@component装饰器中 【provides】[{ provide: Logger, useClass: Logger }],第一个Logger是令牌,第二个属性是类提供商定义对象依赖对象的创建方式为: useClass, useValue, useExisting, useFactoryProvider:(classProvider, valueProvider, existingProvider, FactoryProvider)在Angular中,Provider描述了注入器(Injector)如何初始化令牌(Token)所对应的依赖服务。Provider一个运行时的依赖,注入器依靠它来创建服务对象的实例。接口,方法,字符串不能被当做一个类来处理,所以引入了new InjectionToken()对象注册依赖的提供商,然后我们在@Inject()的帮助下,我们把这个配置对象注入到需要它的构造函数中,最后我们就可以使用最初的那个对象了.
以下是一个测试,关于useClass, useValue, new InjectionToken
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class CarService {
color: string = 'test-CarService';
constructor() {}
}
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AnimalService {
emoji: string = 'test--AnimalService';
constructor() {}
}
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class FlowerService {
emoji: string = 'test--FlowerService';
constructor() {}
}
import { InjectionToken } from '@angular/core';
export interface StudentType {
name: string;
age: number;
}
export const student: StudentType = {
name: 'lee si',
age: 12
};
export const StudentToken = new InjectionToken('student go');
// 非类提供商
以上4个全部注入下面这个组件: const CarServiceConst = { color: 'in const type' }; // 也可在此处修改 providers: [ { provide: FlowerService, useValue: { emoji: 'useValue works' } }, { provide: CarService, useValue: CarServiceConst }, { provide: AnimalService, useClass: FlowerService }, // useClass里的service无需在构造函数里注入 // { provide: AnimalService, useClass: CarService } 这样animal.emoji的值会是undefined // 如果useClass和provide是同一个service,可以不用写在providers里 { provide: StudentToken, useValue: student }, // { provide: StudentFormToken, useClass: StudyFormDefinition } //?StudyFormDefinition ] 。。。 ngOnInit() { console.log('>>>>>> test--FlowerService >|', this.flowerService.emoji); console.log('>>>>>> test--CarService >|', this.carService.color); console.log('>>>>>> test--AnimalService >|', this.animalService.emoji); console.log( '>>>>>> test new InjectionToken() >|', this.studentType.name + this.studentType.age ); // console.log('>>>>>> 测试中', this.studyFormDefinition.startup); }打印如下: useExisting会是同一实例,useClass会是新实例。还是上面这个例子,新增加一个trainService: import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class TrainService { color: string = 'test-TrainService'; constructor() {} }在要注入的这个组件写一个按钮,目的是改变carService的值: click() { this.carService.color = 'change together?'; console.log('>>>>>> test--TrainService >|', this.trainService.color); console.log('>>>>>> test--CarService >|', this.carService.color); }下面看2种情况: 情况1,使用useClass: { provide: TrainService, useClass: CarService } // 这样carService会是2个实例打印如下: 情况2,使用useExisting: { provide: TrainService, useExisting: CarService } // 这样carService会是1个实例打印如下: 1. constructor用法: constructor应该是ES6中明确使用constructor来表示构造函数的,构造函数使用在class中,用来做初始化和给属性赋值操作。当包含constructor的类被实例化时,构造函数将被调用。 constructor也有其用武之地,其主要作用是注入依赖。在constructor中注入的依赖,就可以作为类的属性被使用了。 constructor是在组件就实例化的时候就已经调用了,这也就是说,在constructor中我们是取不到输入属性的值的。,在constructor中不适合进行任何与组件 通信类似的复杂操作,一般在constructor中值进行一些简单的初始化 工作:依赖注入,变量初始化等。 // parent.component.ts import { Component } from '@angular/core'; @Component({ selector: 'exe-parent', template: ` Welcome to Angular WorldHello {{name}} `, }) export class ParentComponent { name: string; constructor() { this.name = 'God eyes'; } } // child.component.ts import { Component, Input, OnInit } from '@angular/core'; @Component({ selector: 'exe-child', template: `父组件的名称:{{pname}} ` }) export class ChildComponent implements OnInit { @Input() pname: string; // 父组件的输入属性 constructor() { console.log('ChildComponent constructor', this.pname); // this.name=undefined } ngOnInit() { // 只有父组件的模板中pname绑定生效后,才执行ngOnInit,所以属性绑定应该在 // ngOnInit内执行相应操作 console.log('ChildComponent ngOnInit', this.pname); // this.name=God eyes } }* 使用构造函数初始化(但直接变量赋值方法更简单): export class AppComponent { title: string; myHero: string; constructor() { this.title = 'Tour of Heroes'; this.myHero = 'Windstorm'; } }* 直接变量赋值方法:【推荐】 export class AppComponent { title = 'Tour of Heroes'; myHero = 'Windstorm'; }2. [ngSwitch] 有一组单选按钮,选中是myVal会改变,ngSwitch会去循环每个case,如果找到了就显示那条case中的数据,不然显示default中的数据 ngSwitch 1 2 3 4 5 ONE TWO THREE FOUR FIVE other当[ngSwitch]里的myVal=2时,显示TWO 3. 父组件向子组件传值 //父组件ts //要传的数据userName userName = 'user1'; //子组件ts import { Component,OnInit,Input, Output, EventEmitter} from '@angular/core'; @Component({ selector: 'app-child', templateUrl: './app-child.component.html' }) export class AppChildComponent implements OnInit { @Input() name:string; ngOnInit() { console.log(this.name) //'user1' } } I, {{hero.name}},am at your service, {{master}} ` }) export class HeroChildComponent { @Input() hero: Hero; @Input() master: string; }4. 子组件向父组件传值 子组件暴露一个 EventEmitter 属性,当事件发生时,子组件利用该属性 emits(向上弹射)事件。父组件绑定到这个事件属性,并在事件发生时作出回应。 angular 报错: Circular dependency detected: Angular 不允许模块之间出现循环依赖,所以不要让模块'A'导入模块'B',而模块'B'又导入模块'A'。 |
CopyRight 2018-2019 实验室设备网 版权所有 |